export interface ActionQueueActive {
    action: string;
    args: any;
    content?: any;
    duration: number;
}

export interface ActionQueueItem {
    actions: ActionQueueActive[];
    flag: string;
}

export interface ActionQueueHistoryItem {
    queueItem: ActionQueueItem;
    startTime: number;
    endTime: number;
    executionTime: number;
    completed: boolean;
}

export class ActionQueue {
    public queue: ActionQueueItem[] = [];
    private history: ActionQueueHistoryItem[] = [];
    private currentActionIndex: number = 0;
    private isPlaying: boolean = false;
    private isPaused: boolean = false;
    private timer: any = null;
    private totalDuration: number = 0;
    private maxHistorySize: number = 100;
    private currentQueueItem: ActionQueueItem | null = null;
    private currentQueueStartTime: number = 0;

    public callables: {
        [key in string]: (args: {
            args: any;
            content: any;
            actionQueue: ActionQueueItem;
            totalDuration: number;
            actionIndex: number;
        }) => void
    } = {};

    add(item: ActionQueueItem) {
        this.queue.push(item);
        this.calculateTotalDuration();
        return this;
    }

    addMultiple(items: ActionQueueItem[]): void {
        this.queue.push(...items);
        this.calculateTotalDuration();
    }

    remove(index: number): boolean {
        if (index >= 0 && index < this.queue.length) {
            // 如果正在执行的是要删除的队列项，先停止
            if (this.currentQueueItem === this.queue[index]) {
                this.stopCurrentQueue();
            }
            this.queue.splice(index, 1);
            this.calculateTotalDuration();
            return true;
        }
        return false;
    }

    removeByFlag(flag: string): number {
        const initialLength = this.queue.length;
        // 如果正在执行的是要删除的队列项，先停止
        if (this.currentQueueItem && this.currentQueueItem.flag === flag) {
            this.stopCurrentQueue();
        }
        this.queue = this.queue.filter(item => item.flag !== flag);
        const removedCount = initialLength - this.queue.length;
        if (removedCount > 0) {
            this.calculateTotalDuration();
        }
        return removedCount;
    }

    update(index: number, item: ActionQueueItem): boolean {
        if (index >= 0 && index < this.queue.length) {
            // 如果正在执行的是要更新的队列项，先停止
            if (this.currentQueueItem === this.queue[index]) {
                this.stopCurrentQueue();
            }
            this.queue[index] = item;
            this.calculateTotalDuration();
            return true;
        }
        return false;
    }

    updateByFlag(flag: string, item: ActionQueueItem): number {
        let updatedCount = 0;
        this.queue = this.queue.map(existingItem => {
            if (existingItem.flag === flag) {
                // 如果正在执行的是要更新的队列项，先停止
                if (this.currentQueueItem === existingItem) {
                    this.stopCurrentQueue();
                }
                updatedCount++;
                return item;
            }
            return existingItem;
        });
        if (updatedCount > 0) {
            this.calculateTotalDuration();
        }
        return updatedCount;
    }

    updateAction(queueIndex: number, actionIndex: number, action: ActionQueueActive): boolean {
        if (queueIndex >= 0 && queueIndex < this.queue.length) {
            const queueItem = this.queue[queueIndex];
            if (actionIndex >= 0 && actionIndex < queueItem.actions.length) {
                // 如果正在执行的是要更新的队列项，先停止
                if (this.currentQueueItem === queueItem) {
                    this.stopCurrentQueue();
                }
                queueItem.actions[actionIndex] = action;
                this.calculateTotalDuration();
                return true;
            }
        }
        return false;
    }

    override(index: number, newItem: ActionQueueItem, play: boolean = true): ActionQueue {
        if (index < 0 || index >= this.queue.length) {
            return this;
        }
        this.stop();
        this.queue[index] = newItem;
        this.calculateTotalDuration();
        if (play) this.play();
        return this;
    }

    playAtActionIndex(queueIndex: number, actionIndex: number): boolean {
        if (queueIndex < 0 || queueIndex >= this.queue.length) {
            return false;
        }
        const queueItem = this.queue[queueIndex];
        if (actionIndex < 0 || actionIndex >= queueItem.actions.length) {
            return false;
        }
        this.stop();
        this.currentQueueItem = queueItem;
        this.currentActionIndex = actionIndex;
        this.playFromCurrentAction();
        return true;
    }

    getAll(): ActionQueueItem[] {
        return [...this.queue];
    }

    get(index: number): ActionQueueItem | null {
        return this.queue[index] || null;
    }

    getByFlag(flag: string): ActionQueueItem[] {
        return this.queue.filter(item => item.flag === flag);
    }

    get length(): number {
        return this.queue.length;
    }

    replaceAll(newQueue: ActionQueueItem[]): void {
        this.stop();
        this.queue = [...newQueue];
        this.calculateTotalDuration();
    }

    play(): void {
        if (this.isPlaying || this.queue.length === 0) {
            return;
        }
        this.isPlaying = true;
        this.isPaused = false;

        // 从队列中取出第一个项开始执行
        this.currentQueueItem = this.queue.shift()!;
        this.currentActionIndex = 0;
        this.currentQueueStartTime = Date.now();

        this.executeNextAction();
    }

    playAt(index: number): void {
        if (index >= 0 && index < this.queue.length) {
            this.stop();
            this.isPlaying = true;
            this.isPaused = false;

            // 取出指定索引的项开始执行
            this.currentQueueItem = this.queue.splice(index, 1)[0];
            this.currentActionIndex = 0;
            this.currentQueueStartTime = Date.now();

            this.executeNextAction();
        }
    }

    pause(): void {
        if (this.isPlaying && !this.isPaused) {
            this.isPaused = true;
            if (this.timer) {
                clearTimeout(this.timer);
                this.timer = null;
            }
        }
    }

    resume(): void {
        if (this.isPlaying && this.isPaused) {
            this.isPaused = false;
            this.executeNextAction();
        }
    }

    stop(): void {
        if (this.currentQueueItem) {
            // 记录未完成的队列到历史
            this.recordQueueCompletion(this.currentQueueItem, false);
        }
        this.isPlaying = false;
        this.isPaused = false;
        this.currentQueueItem = null;
        this.currentActionIndex = 0;
        if (this.timer) {
            clearTimeout(this.timer);
            this.timer = null;
        }
    }

    getStatus(): {
        isPlaying: boolean;
        isPaused: boolean;
        currentQueueItem: ActionQueueItem | null;
        currentActionIndex: number;
        totalItems: number;
        remainingItems: number;
    } {
        return {
            isPlaying: this.isPlaying,
            isPaused: this.isPaused,
            currentQueueItem: this.currentQueueItem,
            currentActionIndex: this.currentActionIndex,
            totalItems: this.queue.length + (this.currentQueueItem ? 1 : 0),
            remainingItems: this.queue.length
        };
    }

    clear(): void {
        this.stop();
        this.queue = [];
        this.totalDuration = 0;
    }

    // 历史记录相关方法
    getHistory(): ActionQueueHistoryItem[] {
        return [...this.history];
    }

    clearHistory(): void {
        this.history = [];
    }

    setMaxHistorySize(size: number): void {
        this.maxHistorySize = Math.max(1, size);
        this.trimHistory();
    }

    getMaxHistorySize(): number {
        return this.maxHistorySize;
    }

    getHistoryStats(): {
        totalExecuted: number;
        totalCompleted: number;
        averageExecutionTime: number;
        successRate: number;
    } {
        if (this.history.length === 0) {
            return {
                totalExecuted: 0,
                totalCompleted: 0,
                averageExecutionTime: 0,
                successRate: 0
            };
        }

        const completed = this.history.filter(item => item.completed).length;
        const totalTime = this.history.reduce((sum, item) => sum + item.executionTime, 0);

        return {
            totalExecuted: this.history.length,
            totalCompleted: completed,
            averageExecutionTime: totalTime / this.history.length,
            successRate: (completed / this.history.length) * 100
        };
    }

    private executeNextAction(): void {
        if (!this.isPlaying || this.isPaused || !this.currentQueueItem) {
            return;
        }

        const currentItem = this.currentQueueItem;

        if (this.currentActionIndex >= currentItem.actions.length) {
            // 当前队列项完成，记录到历史
            this.recordQueueCompletion(currentItem, true);

            // 检查是否还有下一个队列项
            if (this.queue.length > 0) {
                // 执行下一个队列项
                this.currentQueueItem = this.queue.shift()!;
                this.currentActionIndex = 0;
                this.currentQueueStartTime = Date.now();
                this.executeNextAction();
            } else {
                // 所有队列项执行完成
                this.isPlaying = false;
                this.currentQueueItem = null;
                this.currentActionIndex = 0;
            }
            return;
        }

        const action = currentItem.actions[this.currentActionIndex];
        const callable = this.callables[action.action];
        if (callable) {
            callable({
                args: action.args,
                content: action.content,
                actionQueue: currentItem,
                totalDuration: this.totalDuration,
                actionIndex: this.currentActionIndex
            });
        }

        this.timer = setTimeout(() => {
            this.currentActionIndex++;
            this.executeNextAction();
        }, action.duration * 1000);
    }

    private playFromCurrentAction(): void {
        if (this.isPlaying || !this.currentQueueItem) {
            return;
        }
        this.isPlaying = true;
        this.isPaused = false;
        this.currentQueueStartTime = Date.now();
        this.executeNextAction();
    }

    private calculateTotalDuration(): void {
        this.totalDuration = this.queue.reduce((total, item) => {
            return total + item.actions.reduce((itemTotal, action) => itemTotal + action.duration, 0);
        }, 0);
    }

    private stopCurrentQueue(): void {
        if (this.currentQueueItem) {
            this.recordQueueCompletion(this.currentQueueItem, false);
        }
        this.currentQueueItem = null;
        this.currentActionIndex = 0;
        if (this.timer) {
            clearTimeout(this.timer);
            this.timer = null;
        }
    }

    private recordQueueCompletion(queueItem: ActionQueueItem, completed: boolean): void {
        const endTime = Date.now();
        const historyItem: ActionQueueHistoryItem = {
            queueItem: { ...queueItem },
            startTime: this.currentQueueStartTime,
            endTime: endTime,
            executionTime: endTime - this.currentQueueStartTime,
            completed: completed
        };
        this.history.unshift(historyItem);
        this.trimHistory();
    }

    private trimHistory(): void {
        if (this.history.length > this.maxHistorySize) {
            this.history = this.history.slice(0, this.maxHistorySize);
        }
    }

    getTotalDuration(): number {
        return this.totalDuration;
    }

    getRemainingDuration(): number {
        let remaining = 0;

        // 当前正在执行的队列项的剩余时间
        if (this.currentQueueItem) {
            for (let j = this.currentActionIndex; j < this.currentQueueItem.actions.length; j++) {
                remaining += this.currentQueueItem.actions[j].duration;
            }
        }

        // 队列中剩余项的总时间
        for (let i = 0; i < this.queue.length; i++) {
            const queueItem = this.queue[i];
            for (let j = 0; j < queueItem.actions.length; j++) {
                remaining += queueItem.actions[j].duration;
            }
        }

        return remaining;
    }
}